package com.practice.question1;

/**
 * @author 曾庆红
 * {@code @date} 2023-10-18 08:09
 */

import com.zqh.synchronizedDemo.T;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * 创建一个容器，两个线程
 * 一个线程往容器添加10个元素，
 * 一个线程实时监控，当添加五个元素后，这个线程提示结束
 */
public class Solution {
    public static void main(String[] args) {
//        solutionBySynchronized();
        //solutionByCountDown();
        //solutionByLockSupport();
        solutionBySemaphore();
    }
    //必须掌握
    public static void solutionBySynchronized(){
        Container container = new Container();
        final Object lock = new Object();
        Thread t2 = new Thread(()->{
            System.out.println("t2 启动" );
            synchronized (lock){

                if(container.size() != 5){
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("t2 结束");
                lock.notify();
            }

        });

        Thread t1 = new Thread(()->{
            synchronized (lock) {
                for (int i = 0; i < 10; i++) {
                    container.add(new Object());
                    System.out.println("t1 add " + i);
                    if(container.size() == 5){
                        lock.notify();
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
//                    try {
//                        TimeUnit.SECONDS.sleep(1);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
                }
            }
        },"t1");
        t1.start();
        t2.start();
    }

    public static void solutionByCountDown(){
        Container container = new Container();
        CountDownLatch latch = new CountDownLatch(1);
        Thread t2 = new Thread(() -> {
            System.out.println("t2 启动");
            if (container.size() != 5) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("t2 结束");
        },"t2");
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                container.add(new Object());
                System.out.println("t1 add " + i);

                if (container.size() == 5){
                    latch.countDown();
                    try {
                        TimeUnit.MILLISECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    /*try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                }
            }
        },"t1");
        t2.start();
        /*try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        t1.start();
    }

    static Thread t1 = null, t2 = null;
    public static void solutionByLockSupport(){
        Container container = new Container();

        t2 = new Thread(() -> {
            System.out.println("t2 启动");
            if (container.size() != 5) {
                LockSupport.park();
            }
            System.out.println("t2 结束");
            LockSupport.unpark(t1);
        }, "t2");

        t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                container.add(new Object());
                System.out.println("t1 add " + i);
                if (container.size() == 5) {
                    LockSupport.unpark(t2);
                    LockSupport.park();
                }
            }
        }, "t1");

        t1.start();
        t2.start();
        /*try {
            TimeUnit.MILLISECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LockSupport.unpark(t1);*/
    }

    public static void solutionBySemaphore(){
        Container container = new Container();
        Semaphore semaphore = new Semaphore(1);
        t1 = new Thread(()->{
            try {
                semaphore.acquire();
                for (int i = 0; i<5; i++){
                    System.out.println("t1 add "+i);
                }
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.start();
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                semaphore.acquire();
                for (int i = 5; i<10; i++){
                    System.out.println("t1 add "+ i );
                }
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t2 = new Thread(()->{
            //System.out.println("t2 启动");
            try {
                semaphore.acquire();
                System.out.println("t2 结束");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        //t2.start();
    }

}
